package com.ruoyi.project.module.ljw;

import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.poi.ExcelUtil;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.web.page.TableDataInfo;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.common.security.annotation.RequiresPermissions;
import com.ruoyi.project.domain.YqgBarBills;
import com.ruoyi.project.domain.YqgConsumptionDetails;
import com.ruoyi.project.domain.YqgHands;
import com.ruoyi.project.domain.YqgInformationRoom;
import com.ruoyi.project.service.IYqgBarBillsService;
import com.ruoyi.project.service.IYqgConsumptionDetailsService;
import com.ruoyi.project.service.IYqgHandsService;
import com.ruoyi.project.service.IYqgInformationRoomService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 消费详细Controller
 *
 * @author dr
 * @date 2023-04-17
 */
@RestController
@RequestMapping("/ljw/bingpai")
public class LjwYqgBingbaiController extends BaseController {
    @Autowired
    private IYqgConsumptionDetailsService yqgConsumptionDetailsService;
    @Autowired
    private IYqgBarBillsService yqgBarBillsService;
    @Autowired
    private IYqgHandsService yqgHandsService;
    @Autowired
    private IYqgInformationRoomService yqgInformationRoomService;

    /**
     * 查询消费详细列表
     */
    //@RequiresPermissions("project:details:list")
    @GetMapping("/list")
    public TableDataInfo list(YqgConsumptionDetails yqgConsumptionDetails) {
        startPage();
        List<YqgConsumptionDetails> list = yqgConsumptionDetailsService.selectYqgConsumptionDetailsList(yqgConsumptionDetails);
        return getDataTable(list);
    }

    /**
     * 导出消费详细列表
     */
    //@RequiresPermissions("project:details:export")
    @Log(title = "消费详细", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, YqgConsumptionDetails yqgConsumptionDetails) {
        List<YqgConsumptionDetails> list = yqgConsumptionDetailsService.selectYqgConsumptionDetailsList(yqgConsumptionDetails);
        ExcelUtil<YqgConsumptionDetails> util = new ExcelUtil<YqgConsumptionDetails>(YqgConsumptionDetails.class);
        util.exportExcel(response, list, "消费详细数据");
    }

    /**
     * 获取消费详细详细信息
     */
    //@RequiresPermissions("project:details:query")
    @GetMapping(value = "/{ID}")
    public AjaxResult getInfo(@PathVariable("ID") Long ID) {
        return success(yqgConsumptionDetailsService.selectYqgConsumptionDetailsByID(ID));
    }

    /**
     * 新增消费详细
     */
    //@RequiresPermissions("project:details:add")
    @Log(title = "消费详细", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody YqgConsumptionDetails yqgConsumptionDetails) {
        return toAjax(yqgConsumptionDetailsService.insertYqgConsumptionDetails(yqgConsumptionDetails));
    }

    /**
     * 修改消费详细
     */
    //@RequiresPermissions("project:details:edit")
    @Log(title = "消费详细", businessType = BusinessType.UPDATE)
    @PutMapping
    public String edit(@RequestBody YqgConsumptionDetails yqgConsumptionDetails) {

        // 并牌手牌（不用付钱）
        // 获取并牌手牌号
        String handBrand = yqgConsumptionDetails.getHandBrand();
        // 调用判断函数
        String signalH = this.checkHand(handBrand, true);
        // 如果返回不为空
        if (!signalH.equals("")) {
            throw new ServiceException(signalH);
        }

        // 结账手牌（付钱）
        // 获取结账手牌号
        String mergeHand = yqgConsumptionDetails.getMergeHands();
        // 调用判断函数
        String signalM = this.checkHand(mergeHand, false);
        // 如果返回不为空
        if (!signalM.equals("")) {
            return signalM;
        }

        //return new AjaxResult(200, "操作成功");
        return "";
    }

    /**
     * 删除消费详细
     */
    //@RequiresPermissions("project:details:remove")
    @Log(title = "消费详细", businessType = BusinessType.DELETE)
    @DeleteMapping("/{IDs}")
    public AjaxResult remove(@PathVariable Long[] IDs) {
        return toAjax(yqgConsumptionDetailsService.deleteYqgConsumptionDetailsByIDs(IDs));
    }

    /**
     * 判断手牌号是否可执行并牌
     *
     * @param handBrand 要判断的手牌号
     * @param s         判断是并牌手牌还是结账手牌的标志
     *                  true 表示传入的手牌号是并牌手牌
     *                  false 表示传入的手牌号是结账手牌
     */
    public String checkHand(String handBrand, boolean s) {

        // 判断手牌是否存在
        YqgHands yqgHands = new YqgHands(); // 创建手牌表对象，以查找手牌表信息
        // 设置查询参数
        yqgHands.setHandBrand(handBrand); // 设置手牌号
        // 查库
        List<YqgHands> yqgHandsList = yqgHandsService.selectYqgHandsList(yqgHands);
        // 手牌不在库中，即不存在
        if (yqgHandsList.size() == 0) {
            if (s) {
                throw new ServiceException("并牌手牌不存在！");
            } else {
                throw new ServiceException("结账手牌不存在！");
            }
        }
        // 手牌存在
        else {
            // 判断手牌是否开台
            // 手牌状态为"空牌"
            if (yqgHandsList.get(0).getHandState().equals("0")) {
                if (s) {
                    throw new ServiceException("并牌手牌不在台！");
                } else {
                    throw new ServiceException("结账手牌不在台！");
                }
            }
            // 手牌状态为"在台"
            else {
                // 判断手牌是否"锁定"
                // 手牌被"锁定"
                if (yqgHandsList.get(0).getLockedState().equals("0")) {
                    if (s) {
                        throw new ServiceException("并牌手牌已锁定！");
                    } else {
                        throw new ServiceException("结账手牌已锁定！");
                    }
                }
                // 手牌未"锁定"
                else {
                    // 判断是否退房 和 是否下钟
                    YqgConsumptionDetails yqgConsumptionDetails = new YqgConsumptionDetails();
                    yqgConsumptionDetails.setHandBrand(handBrand);
                    yqgConsumptionDetails.setHandState("1");
                    List<YqgConsumptionDetails> list = yqgConsumptionDetailsService.selectYqgConsumptionDetailsList(yqgConsumptionDetails);
                    // 如果该手牌没有消费记录
                    if (list.size() == 0) {
                        if (s) {
                            throw new ServiceException("并牌手牌没有消费记录，不能并牌！");
                        }
                    }
                    // 有消费记录
                    else {
                        for (int i = 0; i < list.size(); i++) {
                            // 判断是否下钟
                            if (list.get(i).getNextClockStatus() != null) {
                                if (list.get(i).getNextClockStatus().equals("1")) {
                                    if (s) {
                                        throw new ServiceException("并牌手牌存在未下钟的消费记录，请下钟后再试！");
                                    }
                                }
                            }
                            // 判断是否退房
                            if (list.get(i).getCheckOutStatus() != null) {
                                if (list.get(i).getCheckOutStatus().equals("1")) {
                                    if (s) {
                                        throw new ServiceException("并牌手牌存在未退房的消费记录，请退房后再试！");
                                    }
                                }
                            }
                        }
                    }
                    // 判断并牌状态
                    YqgBarBills yqgBarBills = new YqgBarBills(); // 新建吧台账单表对象，以查找吧台账单表信息
                    // 设置查询参数
                    yqgBarBills.setHandBrand(handBrand); // 设置手牌号
                    yqgBarBills.setHandState("1"); // 设置手牌状态为"在台"
                    yqgBarBills.setMergeStatus("1"); // 设置并牌状态为"主牌"
                    // 找到0条数据
                    if (yqgBarBillsService.selectYqgBarBillsList(yqgBarBills).size() == 0) {
                        // 说明手牌已经并到其它手牌上
                        // 查找并到了哪个手牌上
                        // 可能是：并后留
                        YqgConsumptionDetails yqgCD = new YqgConsumptionDetails(); // 新建消费详细表对象，以查找消费详细表信息
                        // 设置查询参数
                        yqgCD.setBeforeLeave(handBrand); // 设置留牌前手牌号
                        yqgCD.setHandState("1"); // 设置手牌状态为"在台"
                        yqgCD.setMergeStatus("0"); // 设置手牌状态为"并牌"
                        yqgCD.setRetentionStatus("0"); // 设置留牌状态为"留牌"
                        // 查库
                        List<YqgConsumptionDetails> yqgCDL = yqgConsumptionDetailsService.selectYqgConsumptionDetailsList(yqgCD);
                        // 查到消费记录，获取结账手牌号
                        if (yqgCDL.size() != 0) {
                            if (s) {
                                throw new ServiceException("并牌手牌已并到" + yqgCDL.get(0).getMergeHands() + "上，请取并后再试！");
                            } else {
                                throw new ServiceException("结账手牌已并到" + yqgCDL.get(0).getMergeHands() + "上，请取并后再试！");
                            }
                        }
                        // 可能是：并后未留 或 留后并
                        YqgConsumptionDetails yqgCDs = new YqgConsumptionDetails();
                        // 设置查询参数
                        yqgCDs.setHandBrand(handBrand); // 设置手牌号
                        yqgCDs.setHandState("1"); // 设置手牌状态为"在台"
                        yqgCDs.setMergeStatus("0"); // 设置并牌状态为"并牌"
                        // 查库
                        List<YqgConsumptionDetails> yqgCDList = yqgConsumptionDetailsService.selectYqgConsumptionDetailsList(yqgCDs);
                        // 查到消费记录，获取结账手牌号
                        if (yqgCDList.size() != 0) {
                            if (s) {
                                throw new ServiceException("并牌手牌已并到" + yqgCDList.get(0).getMergeHands() + "上，请取并后再试！");
                            } else {
                                throw new ServiceException("结账手牌已并到" + yqgCDList.get(0).getMergeHands() + "上，请取并后再试！");
                            }
                        }
                    } else {
                        // 未并到其它手牌上
                        // 判断是否被其它手牌并
                        YqgConsumptionDetails yqgCD = new YqgConsumptionDetails(); // 新建消费详细表对象，以查找消费详细表信息
                        // 设置查询参数
                        yqgCD.setMergeHands(handBrand); // 设置并牌手牌
                        yqgCD.setHandState("1"); // 设置手牌状态为"在台"
                        // 查库
                        List<YqgConsumptionDetails> yqgCDL = yqgConsumptionDetailsService.selectYqgConsumptionDetailsList(yqgCD);
                        // 查到数据
                        if (yqgCDL.size() != 0) {
                            // 说明被其它手牌并了
                            // 定义参数
                            List<String> strList = new ArrayList<>(); // 手牌号数组
                            String str = ""; // 手牌号拼接字符串
                            // 循环获取并过来的手牌号
                            for (int i = 0; i < yqgCDL.size(); i++) {
                                // 该手牌未留牌(并后未留,留后并)
                                if (yqgCDL.get(i).getBeforeLeave() == null) {
                                    // 如果手牌号数组中没有数据
                                    if (strList.size() == 0) {
                                        // 将当前手牌号装入数组中
                                        strList.add(yqgCDL.get(i).getHandBrand());
                                        str = str + yqgCDL.get(i).getHandBrand() + ",";
                                    }
                                    // 手牌号数组中有数据
                                    else {
                                        // 遍历手牌号数组，以确定数组中是否存在当前读到的手牌号
                                        for (int j = 0; j < strList.size(); j++) {
                                            // 如果存在
                                            if (strList.get(j).equals(yqgCDL.get(i).getHandBrand())) {
                                                // 直接退出，不再继续判断
                                                break;
                                            } else {
                                                // 且遍历整个手牌号数组都没有退出，即表示不存在
                                                if (j == strList.size() - 1) {
                                                    // 将当前手牌号装入数组中
                                                    strList.add(yqgCDL.get(i).getHandBrand());
                                                    str = str + yqgCDL.get(i).getHandBrand() + ",";
                                                }
                                            }
                                        }
                                    }
                                }
                                // 该手牌是留牌后手牌(并后留)
                                else {
                                    // 如果手牌号数组中没有数据
                                    if (strList.size() == 0) {
                                        // 将留牌前手牌号装入数组中
                                        strList.add(yqgCDL.get(i).getBeforeLeave());
                                        str = str + yqgCDL.get(i).getBeforeLeave() + ",";
                                    }
                                    // 手牌号数组中有数据
                                    else {
                                        // 遍历手牌号数组，以确定数组中是否存在当前读到的留牌前手牌号
                                        for (int j = 0; j < strList.size(); j++) {
                                            // 如果存在
                                            if (strList.get(j).equals(yqgCDL.get(i).getBeforeLeave())) {
                                                // 直接退出，不再继续判断
                                                break;
                                            } else {
                                                // 且遍历整个手牌号数组都没有退出，即表示不存在
                                                if (j == strList.size() - 1) {
                                                    // 将留牌前手牌号装入数组中
                                                    strList.add(yqgCDL.get(i).getBeforeLeave());
                                                    str = str + yqgCDL.get(i).getBeforeLeave() + ",";
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            // 去除拼接字符串末尾的","
                            str = str.substring(0, str.length() - 1);
                            if (s) {
                                return ("并牌手牌已被" + str + "并牌，请取并后再试！");
                            } else {
                                return ("结账手牌已被" + str + "并牌，是否继续并牌？");
                            }
                        }
                    }
                }
            }
        }
        return "";
    }

    /**
     * 并牌方法
     */
    @Log(title = "并牌", businessType = BusinessType.TIEUP, logicalKey = "handBrand")
    @PutMapping("/bing")
    public AjaxResult bingpai(@RequestBody YqgConsumptionDetails yqgConsumptionDetails) {

        // 并牌手牌号（付钱的那个）
        String mergeHandsID = yqgConsumptionDetails.getMergeHands();

        // 获取并牌手牌号（付钱的那个）的吧台账单ID
        YqgBarBills yqgBarBillsMerge = new YqgBarBills();
        yqgBarBillsMerge.setHandBrand(mergeHandsID); // 设置手牌号
        yqgBarBillsMerge.setHandState("1"); // 设置状态（在台）
        //yqgBarBillsMerge.setMergeStatus("1"); // 且不是并牌，是主牌
        //yqgBarBillsMerge.setRetentionStatus("1"); // 且没有留牌，是主牌
        List<YqgBarBills> mergeList = yqgBarBillsService.selectYqgBarBillsList(yqgBarBillsMerge); // 查库
        Long barId = mergeList.get(0).getID(); // 获取吧台账号ID

        // 被并手牌号（不付钱那个）
        String handBrandId = yqgConsumptionDetails.getHandBrand();

        YqgBarBills yqgBarBills = new YqgBarBills();
        yqgBarBills.setHandBrand(handBrandId); // 设置手牌号
        yqgBarBills.setHandState("1"); // 设置状态（在台）
        //yqgBarBills.setMergeStatus("1"); // 且不是并牌，是主牌
        //yqgBarBills.setRetentionStatus("1"); // 且没有留牌，是主牌
        List<YqgBarBills> billsList = yqgBarBillsService.selectYqgBarBillsList(yqgBarBills); // 查库

        // 修改吧台账单表
        yqgBarBills = billsList.get(0);
        yqgBarBills.setMergeStatus("0");
        yqgBarBillsService.updateYqgBarBills(yqgBarBills);

        // 置空
        yqgConsumptionDetails.setMergeHands(null);
        yqgConsumptionDetails.setHandState("1");
        // 修改消费详细表
        List<YqgConsumptionDetails> list = yqgConsumptionDetailsService.selectYqgConsumptionDetailsList(yqgConsumptionDetails);
        // 并牌时间
        Date drawtime = DateUtils.getNowDate();
        if (list.size() != 0) {
            // 批量修改
            for (YqgConsumptionDetails consumptionDetails : list) {
                consumptionDetails.setMergeBarBillsId(barId);
                consumptionDetails.setDrawTime(drawtime);
                consumptionDetails.setMergeHands(mergeHandsID);
                consumptionDetails.setMergeStatus("0");
                consumptionDetails.setRetentionStatus("1");
            }
            // 批量更新
            for (YqgConsumptionDetails consumptionDetails : list) {
                yqgConsumptionDetailsService.updateYqgConsumptionDetails(consumptionDetails);
            }
        }

        // 操作手牌表
        YqgHands yqgHands = new YqgHands();
        yqgHands.setHandBrand(handBrandId);
        List<YqgHands> handlist = yqgHandsService.selectYqgHandsList(yqgHands);
        if (handlist.size() != 0) {
            // 更新手牌表
            yqgHands = handlist.get(0);
            yqgHands.setHandState("1");
            yqgHands.setLockedState("0");
            yqgHandsService.updateYqgHands(yqgHands);
        }

        // 操作房间信息表
        YqgInformationRoom yqgInformationRoom = new YqgInformationRoom();
        yqgInformationRoom.setHandBrand(handBrandId);
        yqgInformationRoom.setHandState("1");
        List<YqgInformationRoom> roomlist = yqgInformationRoomService.selectYqgInformationRoomList(yqgInformationRoom);
        if (roomlist.size() != 0) {
            // 更新房间信息表
            yqgInformationRoom = roomlist.get(0);
            yqgInformationRoom.setHandState("3");
            yqgInformationRoomService.updateYqgInformationRoom(yqgInformationRoom);
        }

        return new AjaxResult(200, "操作成功");
    }
}
